// Package redsync
// @Author zhongxc
// @Date 2023/12/11 15:43:00
// @Desc
package main

import (
	"context"
	"fmt"
	"github.com/go-redsync/redsync/v4"
	"github.com/go-redsync/redsync/v4/redis/goredis/v9"
	goredislib "github.com/redis/go-redis/v9"
	"log"
	"time"
)

func main() {
	// 创建客户端实例
	client := goredislib.NewClient(&goredislib.Options{
		Addr:     "127.0.0.1:6379",
		Password: "",
		DB:       0,
	})
	defer func(client *goredislib.Client) {
		_ = client.Close()
	}(client)

	// 创建Redsync实例
	pool := goredis.NewPool(client)
	rs := redsync.New(pool)

	// 创建锁，设置默认过期时间为10秒钟
	mutexname := "my-global-mutex"
	mutex := rs.NewMutex(mutexname, redsync.WithExpiry(10*time.Second))

	ctx, cancelFunc := context.WithCancel(context.Background())
	defer cancelFunc() // 在函数结束时取消context

	// 尝试获取锁
	if err := mutex.Lock(); err != nil {
		log.Fatalln(err)
	}
	log.Println("Successfully acquired lock")

	// 开启一个goroutine进行自动续期
	go func(ctx context.Context) {
		defer fmt.Println("Goroutine stopped")
		ticker := time.NewTicker(6 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				// 每隔3秒钟（要比锁的过期时间略短），延长锁的过期时间
				if _, err := mutex.Extend(); err != nil {
					log.Println("锁延期失败", err)
				} else {
					log.Println("Lock extended")
				}
			case <-ctx.Done():
				return // 如果context被取消，则结束goroutine
			}
		}
	}(ctx)

	// 完成需要锁的工作
	log.Println("开始处理获取锁后的工作")
	time.Sleep(30 * time.Second)
	log.Println("业务处理成功")

	// 释放锁，以便其他进程或线程可以获得锁
	if ok, err := mutex.Unlock(); !ok || err != nil {
		log.Fatalln("unlock failed", err)
	}
	log.Println("Lock released")
	// time.Sleep(30 * time.Second)
}
